package com.carl.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.carl.common.constant.CartConstant;
import com.carl.common.utils.R;
import com.carl.common.vo.MemberVO;
import com.carl.mall.feign.ProductFeignService;
import com.carl.mall.interceptor.AuthInterceptor;
import com.carl.mall.service.ICartService;
import com.carl.mall.vo.Cart;
import com.carl.mall.vo.CartItem;
import com.carl.mall.vo.SkuInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;


@Service
@Slf4j
public class ICartServiceImpl implements ICartService {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    ThreadPoolExecutor threadPoolExecutor;

    /**
     * 将商品添加到购物车种
     * @param skuId
     * @param num
     * @return
     */
    @Override
    public CartItem addCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cartKeyOperation = getCartKeyOperation();
        Object o = cartKeyOperation.get(skuId.toString());
        if (o!=null){
            //说明已经存在了这个商品那么需要修改这个商品的数量
            System.out.println(o.toString());
            String json = (String)o;
            CartItem item = JSON.parseObject(json, CartItem.class);
            item.setCount(item.getCount()+num);
            cartKeyOperation.put(skuId.toString(),JSON.toJSONString(item));
            return item;
        }
        CartItem item = new CartItem();
        //异步编排任务1不需要返回值
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(()->{
            R r = productFeignService.info(skuId);
            String skuInfoJSON = (String)r.get("skuInfoJson");
            SkuInfoVO skuInfoVO = JSON.parseObject(skuInfoJSON, SkuInfoVO.class);
            //1.设置基础属性
            item.setCheck(true);
            item.setCount(num);
            item.setImage(skuInfoVO.getSkuDefaultImg());
            item.setTitle(skuInfoVO.getSkuTitle());
            item.setPrice(skuInfoVO.getPrice());
            item.setSkuId(skuInfoVO.getSkuId());
        },threadPoolExecutor);
        //2.设置销售属性 异步编排任务1不需要返回值
        CompletableFuture<Void> future2 = CompletableFuture.runAsync(()->{
            List<String> skuSaleAttrs = productFeignService.getSkuSaleAttrs(skuId);
            item.setSkuAttr(skuSaleAttrs);
        },threadPoolExecutor);

        CompletableFuture.allOf(future1,future2).get();
        //3.将数据存入redis中
        cartKeyOperation.put(skuId.toString(),JSON.toJSONString(item));

        return item;
    }

    private BoundHashOperations<String, Object, Object> getCartKeyOperation() {
        //hash  key:cart:1(用户id)  skuId:cartItem
        MemberVO memberVO = AuthInterceptor.threadLocal.get();
        String key = CartConstant.CART_PREFIX + memberVO.getId();
        return redisTemplate.boundHashOps(key);

    }

    @Override
    public Cart getCartList() {
        BoundHashOperations<String, Object, Object> cartKeyOperation = getCartKeyOperation();
        Set<Object> keys = cartKeyOperation.keys();
        Cart cart = new Cart();
        List<CartItem> list = new ArrayList<>();
        for (Object k : keys) {
            String key = (String)k;
            Object o = cartKeyOperation.get(key);
            String json = (String)o;
            //json序列化的目的是调用实体类中的getter方法
            CartItem item = JSON.parseObject(json, CartItem.class);
            list.add(item);
        }
        cart.setItems(list);

        return cart;
    }
}
